// #include "stdafx.h"
#include "WinApi.h"
#include <mutex>

#include <Tlhelp32.h>
#include <psapi.h>

#include <memory>
#pragma comment(lib, "psapi.lib")

WinApi::WinApi(void)
{
    retstringlen = 0;
    WindowVerion = 0;
    IsEuemprosuccess = 0;
    memset(npid, 0, MAX_PATH);
}

WinApi::~WinApi(void) {}

BOOL WinApi::EnumProcessbyName(DWORD dwPID, LPCWSTR ExeName, LONG type)
{
    if (IsEuemprosuccess == 0)
    {
        int nItem = 0; // 项计数
        PROCESSENTRY32W pe32 = {sizeof(PROCESSENTRY32W)};
        HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hProcessSnap == INVALID_HANDLE_VALUE)
            return FALSE;
        if (::Process32FirstW(hProcessSnap, &pe32))
        {
            do
            {
                if (type == 1)
                {
                    if (wcsstr(pe32.szExeFile, ExeName) != NULL) // 模糊匹配
                    {
                        npid[nItem] = pe32.th32ProcessID;
                        IsEuemprosuccess++;
                        nItem++;
                    }
                }
                else
                {
                    if (!_wcsicmp(pe32.szExeFile, ExeName))
                    {
                        npid[nItem] = pe32.th32ProcessID;
                        IsEuemprosuccess++;
                        nItem++;
                    }
                }

            } while (::Process32NextW(hProcessSnap, &pe32));
        }
        ::CloseHandle(hProcessSnap);
        if (IsEuemprosuccess > 0)
            return TRUE;
    }
    else
    {
        for (int i = 0; i < IsEuemprosuccess; i++)
        {
            if (dwPID == npid[i])
                return TRUE;
        }
    }

    return FALSE;
}

DWORD WinApi::FindChildWnd(HWND hchile, const wchar_t *title,
                           const wchar_t *classname, wchar_t *retstring,
                           bool isGW_OWNER, bool isVisible,
                           const wchar_t *process_name)
{
    hchile = ::GetWindow(hchile, GW_HWNDFIRST);
    while (hchile != NULL)
    {
        if (isGW_OWNER) // 判断是否要匹配所有者窗口为0的窗口,即顶级窗口
            if (::GetWindow(hchile, GW_OWNER) != 0)
            {
                hchile = ::GetWindow(hchile, GW_HWNDNEXT); // 获取下一个窗口
                continue;
            }

        if (isVisible) // 判断是否匹配可视窗口
            if (::IsWindowVisible(hchile) == false)
            {
                hchile = ::GetWindow(hchile, GW_HWNDNEXT); // 获取下一个窗口
                continue;
            }
        if (title == NULL && classname == NULL)
        {
            if (process_name)
            {
                DWORD pid = 0;
                GetWindowThreadProcessId(hchile, &pid);
                if (EnumProcessbyName(pid, process_name))
                {
                    if (retstring)
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, hchile);
                        else
                            swprintf(retstring, L"%d", hchile);
                    }
                    else
                        return (DWORD)hchile;
                }
            }
            else
            {
                if (retstring)
                {
                    int len = wcslen(retstring);
                    if (len > 1)
                        swprintf(retstring, L"%s,%d", retstring, hchile);
                    else
                        swprintf(retstring, L"%d", hchile);
                }
                else
                    return (DWORD)hchile;
            }
        }
        else if (title != NULL && classname != NULL)
        {
            wchar_t WindowClassName[MAX_PATH] = {0};
            ::GetClassNameW(hchile, WindowClassName, MAX_PATH);
            wchar_t WindowTitle[MAX_PATH] = {0};
            ::GetWindowTextW(hchile, WindowTitle, MAX_PATH);
            if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
            {
                wchar_t *strfindclass = wcsstr(WindowClassName, classname); // 模糊匹配
                wchar_t *strfindtitle = wcsstr(WindowTitle, title);         // 模糊匹配
                if (strfindclass && strfindtitle)
                {
                    if (process_name) // EnumWindowByProcess
                    {
                        DWORD pid = 0;
                        GetWindowThreadProcessId(hchile, &pid);
                        if (EnumProcessbyName(pid, process_name))
                        {
                            if (retstring)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, hchile);
                                else
                                    swprintf(retstring, L"%d", hchile);
                            }
                            else
                                return (DWORD)hchile;
                        }
                    }
                    else
                    {
                        if (retstring)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, hchile);
                            else
                                swprintf(retstring, L"%d", hchile);
                        }
                        else
                            return (DWORD)hchile;
                    }
                }
            }
        }
        else if (title != NULL)
        {
            wchar_t WindowTitle[MAX_PATH] = {0};
            ::GetWindowTextW(hchile, WindowTitle, MAX_PATH);
            if (wcslen(WindowTitle) > 1)
            {
                wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                if (strfind)
                {
                    if (process_name) // EnumWindowByProcess
                    {
                        DWORD pid = 0;
                        GetWindowThreadProcessId(hchile, &pid);
                        if (EnumProcessbyName(pid, process_name))
                        {
                            if (retstring)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, hchile);
                                else
                                    swprintf(retstring, L"%d", hchile);
                            }
                            else
                                return (DWORD)hchile;
                        }
                    }
                    else
                    {
                        if (retstring)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, hchile);
                            else
                                swprintf(retstring, L"%d", hchile);
                        }
                        else
                            return (DWORD)hchile;
                    }
                }
            }
        }
        else if (classname != NULL)
        {
            wchar_t WindowClassName[MAX_PATH] = {0};
            ::GetClassNameW(hchile, WindowClassName, MAX_PATH);
            if (wcslen(WindowClassName) > 1)
            {
                wchar_t *strfind = wcsstr(WindowClassName, classname); // 模糊匹配
                if (strfind)
                {
                    if (process_name) // EnumWindowByProcess
                    {
                        DWORD pid = 0;
                        GetWindowThreadProcessId(hchile, &pid);
                        if (EnumProcessbyName(pid, process_name))
                        {
                            if (retstring)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, hchile);
                                else
                                    swprintf(retstring, L"%d", hchile);
                            }
                            else
                                return (DWORD)hchile;
                        }
                    }
                    else
                    {
                        if (retstring)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, hchile);
                            else
                                swprintf(retstring, L"%d", hchile);
                        }
                        else
                            return (DWORD)hchile;
                    }
                }
            }
        }

        HWND hchilechile = ::GetWindow(hchile, GW_CHILD);
        if (hchilechile != NULL)
        {
            DWORD dret = FindChildWnd(hchilechile, title, classname, retstring,
                                      isGW_OWNER, isVisible, process_name);
            if (dret > 0)
                break;
        }

        hchile = ::GetWindow(hchile, GW_HWNDNEXT); // 获取下一个窗口
    }
    return 0;
}

// TSEnumWindow:filter整形数: 取值定义如下
//
// 1 : 匹配窗口标题,参数title有效
//
// 2 : 匹配窗口类名,参数class_name有效.
//
// 4 : 只匹配指定父窗口的第一层孩子窗口
//
// 8 : 匹配所有者窗口为0的窗口,即顶级窗口
//
// 16 : 匹配可见的窗口
//
// 32 : 匹配出的窗口按照窗口打开顺序依次排列
bool WinApi::EnumWindow(HWND parent, const wchar_t *title,
                        const wchar_t *class_name, LONG filter,
                        wchar_t *retstring, const wchar_t *process_name)
{
    bool bret = false;
    bool bZwindow = false; // 匹配出的窗口按照窗口打开顺序依次排列
    if (parent == 0)
    {
        parent = GetDesktopWindow();
    }
    if (filter > 32)
    {
        bZwindow = true; // 说明要排序窗口句柄
        filter = filter - 32;
    }

    DWORD procpids[MAX_PATH] = {0};
    int indexpid = 0;
    if (process_name) // EnumWindowByProcess
    {
        if (wcslen(process_name) < 1)
            return false;
        memset(npid, 0, MAX_PATH);
        IsEuemprosuccess = 0;
        if (EnumProcessbyName(0, process_name) == false)
            return false;
    }

    DWORD processpid = 0;
    retstringlen = 0;
    switch (filter)
    {
    case 0: // 所有模式
    {
        if (process_name) // EnumWindowByProcess
        {
            return false;
        }

        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (retstringlen == 0)
                retstringlen = wcslen(retstring);
            if (retstringlen > 1)
                swprintf(retstring, L"%s,%d", retstring, p);
            else
                swprintf(retstring, L"%d", p);
            bret = true;
            HWND hchile = ::GetWindow(p, GW_CHILD);
            if (hchile != NULL)
            {
                FindChildWnd(hchile, NULL, NULL, retstring);
            }

            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 1: // 1 : 匹配窗口标题,参数title有效
    {
        if (wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            wchar_t WindowTitle[MAX_PATH] = {0};
            ::GetWindowTextW(p, WindowTitle, MAX_PATH);
            if (wcslen(WindowTitle) > 1)
            {
                wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                if (strfind)
                {
                    if (process_name) // EnumWindowByProcess
                    {
                        DWORD pid = 0;
                        GetWindowThreadProcessId(p, &pid);
                        if (EnumProcessbyName(pid, process_name))
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    else
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, title, NULL, retstring);
                        }
                    }
                }
            }

            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 2: // 2 : 匹配窗口类名,参数class_name有效.
    {
        if (wcslen(class_name) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            wchar_t WindowClassName[MAX_PATH] = {0};
            ::GetClassNameW(p, WindowClassName, MAX_PATH);
            if (wcslen(WindowClassName) > 1)
            {
                wchar_t *strfind = wcsstr(WindowClassName, class_name); // 模糊匹配
                if (strfind)
                {
                    if (process_name) // EnumWindowByProcess
                    {
                        DWORD pid = 0;
                        GetWindowThreadProcessId(p, &pid);
                        if (EnumProcessbyName(pid, process_name))
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    else
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, NULL, class_name, retstring);
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 3: // 1.窗口标题+2.窗口类名
    {
        if (wcslen(class_name) < 1 && wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            wchar_t WindowClassName[MAX_PATH] = {0};
            ::GetClassNameW(p, WindowClassName, MAX_PATH);
            wchar_t WindowTitle[MAX_PATH] = {0};
            ::GetWindowTextW(p, WindowTitle, MAX_PATH);
            if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
            {
                wchar_t *strfindclass =
                    wcsstr(WindowClassName, class_name);            // 模糊匹配
                wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                if (strfindclass && strfindtitle)
                {
                    if (process_name) // EnumWindowByProcess
                    {
                        DWORD pid = 0;
                        GetWindowThreadProcessId(p, &pid);
                        if (EnumProcessbyName(pid, process_name))
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    else
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, title, class_name, retstring);
                        }
                    }
                }
            }

            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 4: // 4 : 只匹配指定父窗口的第一层孩子窗口
    {
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (process_name) // EnumWindowByProcess
            {
                DWORD pid = 0;
                GetWindowThreadProcessId(p, &pid);
                if (EnumProcessbyName(pid, process_name))
                {
                    if (processpid !=
                        pid) // 只匹配指定映像的所对应的第一个进程.
                             // 可能有很多同映像名的进程，只匹配第一个进程的.
                    {
                        if (indexpid < IsEuemprosuccess)
                        {
                            indexpid++;
                            processpid = pid;
                            memset(retstring, 0, retstringlen); // 清空返回字符串
                            retstringlen = 0;
                        }
                    }
                    if (processpid == pid)
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, NULL, NULL, retstring, false, false,
                                         process_name);
                        }
                    }
                }
            }
            else
            {
                if (retstringlen == 0)
                    retstringlen = wcslen(retstring);
                if (retstringlen > 1)
                    swprintf(retstring, L"%s,%d", retstring, p);
                else
                    swprintf(retstring, L"%d", p);
                bret = true;
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 5: // 1.匹配窗口标题+//4 : 只匹配指定父窗口的第一层孩子窗口
    {
        if (wcslen(title) < 1)
            return false;

        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (process_name) // EnumWindowByProcess
            {
                DWORD pid = 0;
                GetWindowThreadProcessId(p, &pid);
                if (EnumProcessbyName(pid, process_name))
                {
                    if (processpid !=
                        pid) // 只匹配指定映像的所对应的第一个进程.
                             // 可能有很多同映像名的进程，只匹配第一个进程的.
                    {
                        if (indexpid < IsEuemprosuccess)
                        {
                            indexpid++;
                            processpid = pid;
                            memset(retstring, 0, retstringlen); // 清空返回字符串
                            retstringlen = 0;
                        }
                    }
                    if (processpid == pid)
                    {
                        wchar_t WindowTitle[MAX_PATH] = {0};
                        ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                        if (wcslen(WindowTitle) > 1)
                        {
                            if (wcsstr(WindowTitle, title))
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, title, NULL, retstring, false, false,
                                         process_name);
                        }
                    }
                }
            }
            else
            {
                wchar_t WindowTitle[MAX_PATH] = {0};
                ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                if (wcslen(WindowTitle) > 1)
                {
                    if (wcsstr(WindowTitle, title))
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                    }
                }
            }

            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 6: // 2 : 匹配窗口类名+4 : 只匹配指定父窗口的第一层孩子窗口
    {
        if (wcslen(class_name) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (process_name) // EnumWindowByProcess
            {
                DWORD pid = 0;
                GetWindowThreadProcessId(p, &pid);
                if (EnumProcessbyName(pid, process_name))
                {
                    if (indexpid < IsEuemprosuccess)
                    {
                        indexpid++;
                        processpid = pid;
                        memset(retstring, 0, retstringlen); // 清空返回字符串
                        retstringlen = 0;
                    }
                }
                if (processpid == pid)
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    if (wcslen(WindowClassName) > 1)
                    {
                        if (wcsstr(WindowClassName, class_name))
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, NULL, class_name, retstring, false, false,
                                     process_name);
                    }
                }
            }
            else
            {
                wchar_t WindowClassName[MAX_PATH] = {0};
                ::GetClassNameW(p, WindowClassName, MAX_PATH);
                if (wcslen(WindowClassName) > 1)
                {
                    if (wcsstr(WindowClassName, class_name))
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 7: // 1.窗口标题+2.窗口类名+4 : 只匹配指定父窗口的第一层孩子窗口
    {
        if (wcslen(class_name) < 1 && wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (process_name) // EnumWindowByProcess
            {
                DWORD pid = 0;
                GetWindowThreadProcessId(p, &pid);
                if (EnumProcessbyName(pid, process_name))
                {
                    if (indexpid < IsEuemprosuccess)
                    {
                        indexpid++;
                        processpid = pid;
                        memset(retstring, 0, retstringlen); // 清空返回字符串
                        retstringlen = 0;
                    }
                }
                if (processpid == pid)
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfindclass =
                            wcsstr(WindowClassName, class_name);            // 模糊匹配
                        wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfindclass && strfindtitle)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, title, class_name, retstring, false, false,
                                     process_name);
                    }
                }
            }
            else
            {
                wchar_t WindowClassName[MAX_PATH] = {0};
                ::GetClassNameW(p, WindowClassName, MAX_PATH);
                wchar_t WindowTitle[MAX_PATH] = {0};
                ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                {
                    wchar_t *strfindclass =
                        wcsstr(WindowClassName, class_name);            // 模糊匹配
                    wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                    if (strfindclass && strfindtitle)
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                    }
                }
            }

            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 8: // 8 : 匹配所有者窗口为0的窗口,即顶级窗口
    {
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, NULL, NULL, retstring, true, false,
                                         process_name);
                        }
                    }
                }
                else
                {
                    if (retstringlen == 0)
                        retstringlen = wcslen(retstring);
                    if (retstringlen > 1)
                        swprintf(retstring, L"%s,%d", retstring, p);
                    else
                        swprintf(retstring, L"%d", p);
                    bret = true;
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, NULL, NULL, retstring, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 9: // 1.窗口标题+8 : 匹配所有者窗口为0的窗口,即顶级窗口
    {
        if (wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        wchar_t WindowTitle[MAX_PATH] = {0};
                        ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                        if (wcslen(WindowTitle) > 1)
                        {
                            wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                            if (strfind)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, title, NULL, retstring, true, false,
                                         process_name);
                        }
                    }
                }
                else
                {
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, title, NULL, retstring, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 10: // 2.窗口类名+8 : 匹配所有者窗口为0的窗口,即顶级窗口
    {
        if (wcslen(class_name) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        wchar_t WindowClassName[MAX_PATH] = {0};
                        ::GetClassNameW(p, WindowClassName, MAX_PATH);
                        if (wcslen(WindowClassName) > 1)
                        {
                            wchar_t *strfind =
                                wcsstr(WindowClassName, class_name); // 模糊匹配
                            if (strfind)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, NULL, class_name, retstring, true, false,
                                         process_name);
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    if (wcslen(WindowClassName) > 1)
                    {
                        wchar_t *strfind =
                            wcsstr(WindowClassName, class_name); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }

                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, NULL, class_name, retstring, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 11: ////1.窗口标题+2.窗口类名+8 : 匹配所有者窗口为0的窗口,即顶级窗口
    {
        if (wcslen(class_name) < 1 && wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        if (p == NULL)
            return false;
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        wchar_t WindowClassName[MAX_PATH] = {0};
                        ::GetClassNameW(p, WindowClassName, MAX_PATH);
                        wchar_t WindowTitle[MAX_PATH] = {0};
                        ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                        if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                        {
                            wchar_t *strfindclass =
                                wcsstr(WindowClassName, class_name);            // 模糊匹配
                            wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                            if (strfindclass && strfindtitle)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, title, class_name, retstring, true, false,
                                         process_name);
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfindclass =
                            wcsstr(WindowClassName, class_name);            // 模糊匹配
                        wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfindclass && strfindtitle)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, title, class_name, retstring, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 12: // //4 : 只匹配指定父窗口的第一层孩子窗口+8 :
             // 匹配所有者窗口为0的窗口,即顶级窗口
    {
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, NULL, NULL, retstring, true, false,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    if (retstringlen == 0)
                        retstringlen = wcslen(retstring);
                    if (retstringlen > 1)
                        swprintf(retstring, L"%s,%d", retstring, p);
                    else
                        swprintf(retstring, L"%d", p);
                    bret = true;
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 13: // 1.窗口标题+4 : 只匹配指定父窗口的第一层孩子窗口+8 :
             // 匹配所有者窗口为0的窗口,即顶级窗口
    {
        if (wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            wchar_t WindowTitle[MAX_PATH] = {0};
                            ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                            if (wcslen(WindowTitle) > 1)
                            {
                                wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                                if (strfind)
                                {
                                    if (retstringlen == 0)
                                        retstringlen = wcslen(retstring);
                                    if (retstringlen > 1)
                                        swprintf(retstring, L"%s,%d", retstring, p);
                                    else
                                        swprintf(retstring, L"%d", p);
                                    bret = true;
                                }
                            }
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, title, NULL, retstring, true, false,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 14: // 2.窗口类名+4 : 只匹配指定父窗口的第一层孩子窗口+8 :
             // 匹配所有者窗口为0的窗口,即顶级窗口
    {
        if (wcslen(class_name) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            wchar_t WindowClassName[MAX_PATH] = {0};
                            ::GetClassNameW(p, WindowClassName, MAX_PATH);
                            if (wcslen(WindowClassName) > 1)
                            {
                                wchar_t *strfind =
                                    wcsstr(WindowClassName, class_name); // 模糊匹配
                                if (strfind)
                                {
                                    if (retstringlen == 0)
                                        retstringlen = wcslen(retstring);
                                    if (retstringlen > 1)
                                        swprintf(retstring, L"%s,%d", retstring, p);
                                    else
                                        swprintf(retstring, L"%d", p);
                                    bret = true;
                                }
                            }
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, NULL, class_name, retstring, true, false,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    if (wcslen(WindowClassName) > 1)
                    {
                        wchar_t *strfind =
                            wcsstr(WindowClassName, class_name); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 15: ////1.窗口标题+2.窗口类名+4 : 只匹配指定父窗口的第一层孩子窗口+8 :
             /// 匹配所有者窗口为0的窗口,即顶级窗口
    {
        if (wcslen(class_name) < 1 && wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            wchar_t WindowClassName[MAX_PATH] = {0};
                            ::GetClassNameW(p, WindowClassName, MAX_PATH);
                            wchar_t WindowTitle[MAX_PATH] = {0};
                            ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                            if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                            {
                                wchar_t *strfindclass =
                                    wcsstr(WindowClassName, class_name); // 模糊匹配
                                wchar_t *strfindtitle =
                                    wcsstr(WindowTitle, title); // 模糊匹配
                                if (strfindclass && strfindtitle)
                                {
                                    if (retstringlen == 0)
                                        retstringlen = wcslen(retstring);
                                    if (retstringlen > 1)
                                        swprintf(retstring, L"%s,%d", retstring, p);
                                    else
                                        swprintf(retstring, L"%d", p);
                                    bret = true;
                                }
                            }
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, title, class_name, retstring, true,
                                             false, process_name);
                            }
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfindclass =
                            wcsstr(WindowClassName, class_name);            // 模糊匹配
                        wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfindclass && strfindtitle)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 16: // 匹配可见的窗口
    {
        parent = GetDesktopWindow();
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p))
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, NULL, NULL, retstring, false, true,
                                         process_name);
                        }
                    }
                }
                else
                {
                    if (retstringlen == 0)
                        retstringlen = wcslen(retstring);
                    if (retstringlen > 1)
                        swprintf(retstring, L"%s,%d", retstring, p);
                    else
                        swprintf(retstring, L"%d", p);
                    bret = true;
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, NULL, NULL, retstring, false, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 17: // 1.窗口标题+//匹配可见的窗口
    {
        if (wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p))
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        wchar_t WindowTitle[MAX_PATH] = {0};
                        ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                        if (wcslen(WindowTitle) > 1)
                        {
                            wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                            if (strfind)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, title, NULL, retstring, false, true,
                                         process_name);
                        }
                    }
                }
                else
                {
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, title, NULL, retstring, false, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 18: // 2.窗口类名+//匹配可见的窗口
    {
        if (wcslen(class_name) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p))
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        wchar_t WindowClassName[MAX_PATH] = {0};
                        ::GetClassNameW(p, WindowClassName, MAX_PATH);
                        if (wcslen(WindowClassName) > 1)
                        {
                            wchar_t *strfind =
                                wcsstr(WindowClassName, class_name); // 模糊匹配
                            if (strfind)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, NULL, class_name, retstring, false, true,
                                         process_name);
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    if (wcslen(WindowClassName) > 1)
                    {
                        wchar_t *strfind =
                            wcsstr(WindowClassName, class_name); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, NULL, class_name, retstring, false, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 19: ////1.窗口标题+2.窗口类名+匹配可见的窗口
    {
        if (wcslen(class_name) < 1 && wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p))
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        wchar_t WindowClassName[MAX_PATH] = {0};
                        ::GetClassNameW(p, WindowClassName, MAX_PATH);
                        wchar_t WindowTitle[MAX_PATH] = {0};
                        ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                        if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                        {
                            wchar_t *strfindclass =
                                wcsstr(WindowClassName, class_name);            // 模糊匹配
                            wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                            if (strfindclass && strfindtitle)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, title, class_name, retstring, false, true,
                                         process_name);
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfindclass =
                            wcsstr(WindowClassName, class_name);            // 模糊匹配
                        wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfindclass && strfindtitle)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, title, class_name, retstring, false, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 20: // 4 : 只匹配指定父窗口的第一层孩子窗口+匹配可见的窗口
    {
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p))
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, NULL, NULL, retstring, false, true,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    if (retstringlen == 0)
                        retstringlen = wcslen(retstring);
                    if (retstringlen > 1)
                        swprintf(retstring, L"%s,%d", retstring, p);
                    else
                        swprintf(retstring, L"%d", p);
                    bret = true;
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 21: // 1.窗口标题+4 : 只匹配指定父窗口的第一层孩子窗口+匹配可见的窗口
    {
        if (wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p))
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            wchar_t WindowTitle[MAX_PATH] = {0};
                            ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                            if (wcslen(WindowTitle) > 1)
                            {
                                wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                                if (strfind)
                                {
                                    if (retstringlen == 0)
                                        retstringlen = wcslen(retstring);
                                    if (retstringlen > 1)
                                        swprintf(retstring, L"%s,%d", retstring, p);
                                    else
                                        swprintf(retstring, L"%d", p);
                                    bret = true;
                                }
                            }
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, title, NULL, retstring, false, true,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 22: // 2.窗口类名+4 : 只匹配指定父窗口的第一层孩子窗口+匹配可见的窗口
    {
        if (wcslen(class_name) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p))
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            wchar_t WindowClassName[MAX_PATH] = {0};
                            ::GetClassNameW(p, WindowClassName, MAX_PATH);
                            if (wcslen(WindowClassName) > 1)
                            {
                                wchar_t *strfind =
                                    wcsstr(WindowClassName, class_name); // 模糊匹配
                                if (strfind)
                                {
                                    if (retstringlen == 0)
                                        retstringlen = wcslen(retstring);
                                    if (retstringlen > 1)
                                        swprintf(retstring, L"%s,%d", retstring, p);
                                    else
                                        swprintf(retstring, L"%d", p);
                                    bret = true;
                                }
                            }
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, NULL, class_name, retstring, false, true,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    if (wcslen(WindowClassName) > 1)
                    {
                        wchar_t *strfind =
                            wcsstr(WindowClassName, class_name); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 23: // 1.窗口标题+2.窗口类名+4 :
             // 只匹配指定父窗口的第一层孩子窗口+匹配可见的窗口
    {
        if (wcslen(class_name) < 1 && wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p))
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            wchar_t WindowClassName[MAX_PATH] = {0};
                            ::GetClassNameW(p, WindowClassName, MAX_PATH);
                            wchar_t WindowTitle[MAX_PATH] = {0};
                            ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                            if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                            {
                                wchar_t *strfindclass =
                                    wcsstr(WindowClassName, class_name); // 模糊匹配
                                wchar_t *strfindtitle =
                                    wcsstr(WindowTitle, title); // 模糊匹配
                                if (strfindclass && strfindtitle)
                                {
                                    if (retstringlen == 0)
                                        retstringlen = wcslen(retstring);
                                    if (retstringlen > 1)
                                        swprintf(retstring, L"%s,%d", retstring, p);
                                    else
                                        swprintf(retstring, L"%d", p);
                                    bret = true;
                                }
                            }
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, title, class_name, retstring, false,
                                             true, process_name);
                            }
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfindclass =
                            wcsstr(WindowClassName, class_name);            // 模糊匹配
                        wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfindclass && strfindtitle)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 24: // 8 : 匹配所有者窗口为0的窗口,即顶级窗口+16.匹配可见的窗口
    {
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (retstringlen == 0)
                            retstringlen = wcslen(retstring);
                        if (retstringlen > 1)
                            swprintf(retstring, L"%s,%d", retstring, p);
                        else
                            swprintf(retstring, L"%d", p);
                        bret = true;
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, NULL, NULL, retstring, true, true,
                                         process_name);
                        }
                    }
                }
                else
                {
                    if (retstringlen == 0)
                        retstringlen = wcslen(retstring);
                    if (retstringlen > 1)
                        swprintf(retstring, L"%s,%d", retstring, p);
                    else
                        swprintf(retstring, L"%d", p);
                    bret = true;

                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, NULL, NULL, retstring, true, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 25: // 1.窗口标题+
             // 8:匹配所有者窗口为0的窗口,即顶级窗口+16.匹配可见的窗口
    {
        if (wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        wchar_t WindowTitle[MAX_PATH] = {0};
                        ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                        if (wcslen(WindowTitle) > 1)
                        {
                            wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                            if (strfind)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, title, NULL, retstring, true, true,
                                         process_name);
                        }
                    }
                }
                else
                {
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, title, NULL, retstring, true, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 26: // 2.窗口类名+
             // 8:匹配所有者窗口为0的窗口,即顶级窗口+16.匹配可见的窗口
    {
        if (wcslen(class_name) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        wchar_t WindowClassName[MAX_PATH] = {0};
                        ::GetClassNameW(p, WindowClassName, MAX_PATH);
                        if (wcslen(WindowClassName) > 1)
                        {
                            wchar_t *strfind =
                                wcsstr(WindowClassName, class_name); // 模糊匹配
                            if (strfind)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, NULL, class_name, retstring, true, true,
                                         process_name);
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    if (wcslen(WindowClassName) > 1)
                    {
                        wchar_t *strfind =
                            wcsstr(WindowClassName, class_name); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, NULL, class_name, retstring, true, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 27: // 1.窗口标题+2.窗口类名+8:匹配所有者窗口为0的窗口,即顶级窗口+16.匹配可见的窗口
    {
        if (wcslen(class_name) < 1 && wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        wchar_t WindowClassName[MAX_PATH] = {0};
                        ::GetClassNameW(p, WindowClassName, MAX_PATH);
                        wchar_t WindowTitle[MAX_PATH] = {0};
                        ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                        if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                        {
                            wchar_t *strfindclass =
                                wcsstr(WindowClassName, class_name);            // 模糊匹配
                            wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                            if (strfindclass && strfindtitle)
                            {
                                if (retstringlen == 0)
                                    retstringlen = wcslen(retstring);
                                if (retstringlen > 1)
                                    swprintf(retstring, L"%s,%d", retstring, p);
                                else
                                    swprintf(retstring, L"%d", p);
                                bret = true;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            FindChildWnd(hchile, title, class_name, retstring, true, true,
                                         process_name);
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfindclass =
                            wcsstr(WindowClassName, class_name);            // 模糊匹配
                        wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfindclass && strfindtitle)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                    HWND hchile = ::GetWindow(p, GW_CHILD);
                    if (hchile != NULL)
                    {
                        FindChildWnd(hchile, title, class_name, retstring, true, true);
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 28: // 4 :
             // 只匹配指定父窗口的第一层孩子窗口+8:匹配所有者窗口为0的窗口,即顶级窗口+16.匹配可见的窗口
    {
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, NULL, NULL, retstring, true, true,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    if (retstringlen == 0)
                        retstringlen = wcslen(retstring);
                    if (retstringlen > 1)
                        swprintf(retstring, L"%s,%d", retstring, p);
                    else
                        swprintf(retstring, L"%d", p);
                    bret = true;
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 29: ////1.窗口标题+4 :
             /// 只匹配指定父窗口的第一层孩子窗口+8:匹配所有者窗口为0的窗口,即顶级窗口+16.匹配可见的窗口
    {
        if (wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            wchar_t WindowTitle[MAX_PATH] = {0};
                            ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                            if (wcslen(WindowTitle) > 1)
                            {
                                wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                                if (strfind)
                                {
                                    if (retstringlen == 0)
                                        retstringlen = wcslen(retstring);
                                    if (retstringlen > 1)
                                        swprintf(retstring, L"%s,%d", retstring, p);
                                    else
                                        swprintf(retstring, L"%d", p);
                                    bret = true;
                                }
                            }
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, title, NULL, retstring, true, true,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfind = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 30: // 2.窗口类名+4 :
             // 只匹配指定父窗口的第一层孩子窗口+8:匹配所有者窗口为0的窗口,即顶级窗口+16.匹配可见的窗口
    {
        if (wcslen(class_name) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            wchar_t WindowClassName[MAX_PATH] = {0};
                            ::GetClassNameW(p, WindowClassName, MAX_PATH);
                            if (wcslen(WindowClassName) > 1)
                            {
                                wchar_t *strfind =
                                    wcsstr(WindowClassName, class_name); // 模糊匹配
                                if (strfind)
                                {
                                    if (retstringlen == 0)
                                        retstringlen = wcslen(retstring);
                                    if (retstringlen > 1)
                                        swprintf(retstring, L"%s,%d", retstring, p);
                                    else
                                        swprintf(retstring, L"%d", p);
                                    bret = true;
                                }
                            }
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, NULL, class_name, retstring, true, true,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    if (wcslen(WindowClassName) > 1)
                    {
                        wchar_t *strfind =
                            wcsstr(WindowClassName, class_name); // 模糊匹配
                        if (strfind)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    case 31: // 1.窗口标题+2.窗口类名+4 :
             // 只匹配指定父窗口的第一层孩子窗口+8:匹配所有者窗口为0的窗口,即顶级窗口+16.匹配可见的窗口
    {
        if (wcslen(class_name) < 1 && wcslen(title) < 1)
            return false;
        HWND p = ::GetWindow(parent, GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                if (process_name) // EnumWindowByProcess
                {
                    DWORD pid = 0;
                    GetWindowThreadProcessId(p, &pid);
                    if (EnumProcessbyName(pid, process_name))
                    {
                        if (processpid !=
                            pid) // 只匹配指定映像的所对应的第一个进程.
                                 // 可能有很多同映像名的进程，只匹配第一个进程的.
                        {
                            if (indexpid < IsEuemprosuccess)
                            {
                                indexpid++;
                                processpid = pid;
                                memset(retstring, 0, retstringlen); // 清空返回字符串
                                retstringlen = 0;
                            }
                        }
                        if (processpid == pid)
                        {
                            wchar_t WindowClassName[MAX_PATH] = {0};
                            ::GetClassNameW(p, WindowClassName, MAX_PATH);
                            wchar_t WindowTitle[MAX_PATH] = {0};
                            ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                            if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                            {
                                wchar_t *strfindclass =
                                    wcsstr(WindowClassName, class_name); // 模糊匹配
                                wchar_t *strfindtitle =
                                    wcsstr(WindowTitle, title); // 模糊匹配
                                if (strfindclass && strfindtitle)
                                {
                                    if (retstringlen == 0)
                                        retstringlen = wcslen(retstring);
                                    if (retstringlen > 1)
                                        swprintf(retstring, L"%s,%d", retstring, p);
                                    else
                                        swprintf(retstring, L"%d", p);
                                    bret = true;
                                }
                            }
                            HWND hchile = ::GetWindow(p, GW_CHILD);
                            if (hchile != NULL)
                            {
                                FindChildWnd(hchile, title, class_name, retstring, true, true,
                                             process_name);
                            }
                        }
                    }
                }
                else
                {
                    wchar_t WindowClassName[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClassName, MAX_PATH);
                    wchar_t WindowTitle[MAX_PATH] = {0};
                    ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                    if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                    {
                        wchar_t *strfindclass =
                            wcsstr(WindowClassName, class_name);            // 模糊匹配
                        wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                        if (strfindclass && strfindtitle)
                        {
                            if (retstringlen == 0)
                                retstringlen = wcslen(retstring);
                            if (retstringlen > 1)
                                swprintf(retstring, L"%s,%d", retstring, p);
                            else
                                swprintf(retstring, L"%d", p);
                            bret = true;
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
        break;
    }
    default:
        return bret;
    }

    return bret;
}

bool WinApi::EnumWindowSuper(wchar_t *spec1, LONG flag1, LONG type1,
                             wchar_t *spec2, LONG flag2, LONG type2, LONG sort,
                             wchar_t *retstring)
{
    bool bret = false;
    wchar_t findhwnd1[MAX_PATH * 100] = {0};
    wchar_t findhwnd2[MAX_PATH * 100] = {0};
    bool bfindhwnd1 = false;
    bool bfindhwnd2 = false;
    retstringlen = 0;
    HWND parent = GetDesktopWindow();
    HWND p = ::GetWindow(parent, GW_CHILD);
    p = ::GetWindow(p, GW_HWNDFIRST);
    while (p != NULL)
    {
        if (flag1 == 0) // 0表示spec1的内容是标题
        {
            wchar_t WindowTitle[MAX_PATH] = {0};
            ::GetWindowTextW(p, WindowTitle, MAX_PATH);
            if (wcslen(WindowTitle) > 0)
            {
                if (type1 == 0) // 0精确判断,1模糊判断
                {
                    if (wcscmp(spec1, WindowTitle) == 0)
                        bfindhwnd1 = true;
                }
                else if (type1 == 1)
                {
                    if (wcsstr(WindowTitle, spec1) != NULL)
                        bfindhwnd1 = true;
                }
            }
        }
        else if (flag1 == 1) // 1表示spec1的内容是程序名字
        {
            DWORD pid = 0;
            ::GetWindowThreadProcessId(p, &pid);
            wchar_t proname[MAX_PATH] = {0};
            GetProcesspath(pid, proname);
        }
        else if (flag1 == 2) // 2表示spec1的内容是类名
        {
            wchar_t WindowClassName[MAX_PATH] = {0};
            ::GetClassNameW(p, WindowClassName, MAX_PATH);
            if (wcslen(WindowClassName) > 0)
            {
                if (type1 == 0) // 0精确判断,1模糊判断
                {
                    if (wcscmp(spec1, WindowClassName) == 0)
                        bfindhwnd1 = true;
                }
                else
                {
                    if (wcsstr(WindowClassName, spec1) != NULL)
                        bfindhwnd1 = true;
                }
            }
        }
        if (bfindhwnd1)
        {
            if (retstringlen == 0)
                retstringlen = wcslen(retstring);
            if (retstringlen > 1)
                swprintf(retstring, L"%s,%d", retstring, p);
            else
                swprintf(retstring, L"%d", p);
            bfindhwnd1 = false;
        }

        HWND hchile = ::GetWindow(p, GW_CHILD);
        if (hchile != NULL)
        {
            FindChildWnd(hchile, NULL, NULL, findhwnd1);
        }
        p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
    }

    return bret;
}

bool WinApi::EnumProcess(const wchar_t *name, wchar_t *retstring)
{
    bool bret = false;
    retstringlen = 0;
    if (wcslen(name) < 1)
        return false;
    IsEuemprosuccess = 0;
    if (EnumProcessbyName(0, name) == true)
    {
        bret = true;
        for (int i = 0; i < IsEuemprosuccess; i++)
        {
            if (retstringlen == 0)
                retstringlen = wcslen(retstring);
            if (retstringlen > 1)
                swprintf(retstring, L"%s,%d", retstring, npid[i]);
            else
                swprintf(retstring, L"%d", npid[i]);
        }
    }
    return bret;
}
bool WinApi::ClientToScreen(LONG hwnd, LONG &x, LONG &y)
{
    POINT point;

    point.x = x;
    point.y = y;
    ::ClientToScreen((HWND)hwnd, &point);
    x = point.x;
    y = point.y;

    return true;
}
long WinApi::FindWindow(const wchar_t *class_name, const wchar_t *title)
{
    if (class_name[0] == L'\0')
        class_name = nullptr;
    if (title[0] == L'\0')
        title = nullptr;
    return (LONG)::FindWindowW(class_name, title);
}

long WinApi::FindWindowEx(long parent, const wchar_t *class_name,
                          const wchar_t *title)
{
    if (class_name[0] == L'\0')
        class_name = nullptr;
    if (title[0] == L'\0')
        title = nullptr;
    return (long)::FindWindowExW((HWND)parent, NULL, class_name, title);
}

bool WinApi::FindWindowByProcess(const wchar_t *class_name,
                                 const wchar_t *title, LONG &rethwnd,
                                 const wchar_t *process_name, DWORD Pid)
{
    bool bret = false;
    rethwnd = 0;
    if (process_name)
    {
        if (wcslen(process_name) < 1)
            return false;
        memset(npid, 0, MAX_PATH);
        IsEuemprosuccess = 0;
        if (EnumProcessbyName(0, process_name) == false)
            return false;

        HWND p = ::GetWindow(GetDesktopWindow(), GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                DWORD pid = 0;
                GetWindowThreadProcessId(p, &pid);
                if (EnumProcessbyName(pid, process_name))
                {
                    if (wcslen(class_name) < 1 && wcslen(title) < 1)
                    {
                        rethwnd = (LONG)p;
                        bret = true;
                        break;
                    }
                    else
                    {
                        wchar_t WindowClassName[MAX_PATH] = {0};
                        ::GetClassNameW(p, WindowClassName, MAX_PATH);
                        wchar_t WindowTitle[MAX_PATH] = {0};
                        ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                        if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                        {
                            wchar_t *strfindclass =
                                wcsstr(WindowClassName, class_name);            // 模糊匹配
                            wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                            if ((wcslen(class_name) >= 1 && strfindclass) ||
                                (wcslen(title) >= 1 && strfindtitle))
                            {
                                rethwnd = (LONG)p;
                                bret = true;
                                break;
                            }
                        }

                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            const wchar_t *classname = NULL;
                            const wchar_t *titles = NULL;
                            if (wcslen(class_name) > 0)
                                classname = class_name;
                            if (wcslen(title) > 0)
                                titles = titles;
                            DWORD dret = FindChildWnd(hchile, titles, classname, NULL, false,
                                                      false, process_name);
                            if (dret > 0)
                            {
                                rethwnd = (LONG)dret;
                                bret = true;
                                break;
                            }
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
    }
    else if (Pid > 0)
    {
        HWND p = ::GetWindow(GetDesktopWindow(), GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                DWORD npid = 0;
                GetWindowThreadProcessId(p, &npid);
                if (Pid == npid)
                {
                    if (wcslen(class_name) < 1 && wcslen(title) < 1)
                    {
                        rethwnd = (LONG)p;
                        bret = true;
                        break;
                    }
                    else
                    {
                        wchar_t WindowClassName[MAX_PATH] = {0};
                        ::GetClassNameW(p, WindowClassName, MAX_PATH);
                        wchar_t WindowTitle[MAX_PATH] = {0};
                        ::GetWindowTextW(p, WindowTitle, MAX_PATH);
                        if (wcslen(WindowClassName) > 1 && wcslen(WindowTitle) > 1)
                        {
                            wchar_t *strfindclass =
                                wcsstr(WindowClassName, class_name);            // 模糊匹配
                            wchar_t *strfindtitle = wcsstr(WindowTitle, title); // 模糊匹配
                            if ((wcslen(class_name) >= 1 && strfindclass) ||
                                (wcslen(title) >= 1 && strfindtitle))
                            {
                                rethwnd = (LONG)p;
                                bret = true;
                                break;
                            }
                        }
                        HWND hchile = ::GetWindow(p, GW_CHILD);
                        if (hchile != NULL)
                        {
                            const wchar_t *classname = NULL;
                            const wchar_t *titles = NULL;
                            if (wcslen(class_name) > 0)
                                classname = class_name;
                            if (wcslen(title) > 0)
                                titles = titles;
                            DWORD dret = FindChildWnd(hchile, titles, classname, NULL, false,
                                                      false, process_name);
                            if (dret > 0)
                            {
                                rethwnd = (LONG)dret;
                                bret = true;
                                break;
                            }
                        }
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
    }

    return bret;
}
bool WinApi::GetClientRect(LONG hwnd, LONG &x, LONG &y, LONG &x1, LONG &y1)
{
    bool bret = false;
    RECT clientrect;
    if (IsWindow((HWND)hwnd))
    {
        ::GetClientRect((HWND)hwnd, &clientrect);
        POINT point;
        point.x = clientrect.left;
        point.y = clientrect.top;
        ::ClientToScreen((HWND)hwnd, &point);
        x = point.x;
        y = point.y;
        point.x = clientrect.right;
        point.y = clientrect.bottom;
        ::ClientToScreen((HWND)hwnd, &point);
        x1 = point.x;
        y1 = point.y;
        bret = true;
    }

    return bret;
}
bool WinApi::GetClientSize(LONG hwnd, LONG &width, LONG &height)
{
    bool bret = false;
    RECT clientrect;
    if (IsWindow((HWND)hwnd))
    {
        ::GetClientRect((HWND)hwnd, &clientrect);
        width = clientrect.right - clientrect.left;
        height = clientrect.bottom - clientrect.top;
        bret = true;
    }
    return bret;
}
bool WinApi::GetMousePointWindow(LONG &rethwnd, LONG x, LONG y)
{
    bool bret = false;
    rethwnd = 0;
    POINT point;
    if ((x != -1 && y != -1))
    {
        point.x = x;
        point.y = y;
    }
    else
    {
        ::GetCursorPos(&point);
    }
    rethwnd = (DWORD)::WindowFromPoint(point);
    if (rethwnd == NULL)
    {
        HWND p = ::GetWindow(GetDesktopWindow(), GW_CHILD); // 获取桌面窗口的子窗口
        p = ::GetWindow(p, GW_HWNDFIRST);
        while (p != NULL)
        {
            if (::IsWindowVisible(p) && ::GetWindow(p, GW_OWNER) == 0)
            {
                RECT rc;
                ::GetWindowRect(p, &rc);
                if ((rc.top <= point.y) && (rc.left <= point.x) &&
                    (rc.right >= (point.x - rc.left)) &&
                    (rc.bottom >= (point.y - rc.top)))
                {
                    wchar_t WindowClass[MAX_PATH] = {0};
                    ::GetClassNameW(p, WindowClass, MAX_PATH);
                    // if((windowpoint.x==0||windowpoint.x<rc.left)&&wcscmp(WindowClass,L"CabinetWClass")!=0)
                    // //IE框窗体排除在外
                    if (wcscmp(WindowClass, L"CabinetWClass") != 0) // IE框窗体排除在外
                    {
                        rethwnd = (DWORD)p;
                        bret = true;
                        break;
                    }
                }
            }
            p = ::GetWindow(p, GW_HWNDNEXT); // 获取下一个窗口
        }
    }
    else
        bret = true;

    return bret;
}

int WinApi::GetProcessNumber() // 获取CPU个数
{
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    return (int)info.dwNumberOfProcessors;
}

// 时间格式转换
__int64 WinApi::FileTimeToInt64(const FILETIME &time)
{
    ULARGE_INTEGER tt;
    tt.LowPart = time.dwLowDateTime;
    tt.HighPart = time.dwHighDateTime;
    return (tt.QuadPart);
}

double WinApi::get_cpu_usage(DWORD ProcessID) // 获取指定进程CPU使用率
{
    // cpu数量
    static int processor_count_ = -1;
    // 上一次的时间
    static __int64 last_time_ = 0;
    static __int64 last_system_time_ = 0;

    FILETIME now;
    FILETIME creation_time;
    FILETIME exit_time;
    FILETIME kernel_time;
    FILETIME user_time;
    __int64 system_time;
    __int64 time;
    // 	__int64 system_time_delta;
    // 	__int64 time_delta;

    double cpu = -1;

    if (processor_count_ == -1)
    {
        processor_count_ = GetProcessNumber();
    }

    GetSystemTimeAsFileTime(&now);

    // HANDLE hProcess =
    // OpenProcess(PROCESS_QUERY_INFORMATION/*PROCESS_ALL_ACCESS*/, false,
    // ProcessID);
    HANDLE hProcess = NULL;

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
                           ProcessID);

    if (!hProcess)
    {
        return -1;
    }
    if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time,
                         &user_time))
    {
        return -1;
    }
    system_time = (FileTimeToInt64(kernel_time) + FileTimeToInt64(user_time)) /
                  processor_count_; // CPU使用时间
    time = FileTimeToInt64(now);    // 现在的时间

    last_system_time_ = system_time;
    last_time_ = time;
    CloseHandle(hProcess);

    Sleep(1000);

    // hProcess = OpenProcess(PROCESS_QUERY_INFORMATION/*PROCESS_ALL_ACCESS*/,
    // false, ProcessID);

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
                           ProcessID);

    if (!hProcess)
    {
        return -1;
    }
    if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time,
                         &user_time))
    {
        return -1;
    }
    GetSystemTimeAsFileTime(&now);
    system_time = (FileTimeToInt64(kernel_time) + FileTimeToInt64(user_time)) /
                  processor_count_; // CPU使用时间
    time = FileTimeToInt64(now);    // 现在的时间

    CloseHandle(hProcess);

    cpu = ((double)(system_time - last_system_time_) /
           (double)(time - last_time_)) *
          100;
    return cpu;
}

// 或者指定进程内存使用率
DWORD WinApi::GetMemoryInfo(DWORD ProcessID)
{
    PROCESS_MEMORY_COUNTERS pmc;
    DWORD memoryInK = 0;
    HANDLE hProcess = NULL;

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
                           ProcessID);

    if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
    {
        // memoryInK = pmc.WorkingSetSize/1024;		//单位为k
        memoryInK = pmc.WorkingSetSize;
    }

    CloseHandle(hProcess);
    return memoryInK;
}

bool WinApi::GetProcessInfo(LONG pid, wchar_t *retstring)
{
    bool bret = false;
    wchar_t process_name[MAX_PATH] = {0};
    wchar_t process_path[MAX_PATH] = {0};
    DWORD cpu = 0;
    DWORD meminfo = 0;

    int nItem = 0; // 项计数
    PROCESSENTRY32W pe32 = {sizeof(PROCESSENTRY32W)};
    HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
        return FALSE;
    if (::Process32FirstW(hProcessSnap, &pe32))
    {
        do
        {
            if (pe32.th32ProcessID == pid)
            {
                wcscpy(process_name, pe32.szExeFile);
                break;
            }

        } while (::Process32NextW(hProcessSnap, &pe32));
    }
    ::CloseHandle(hProcessSnap);
    if (wcslen(process_name) < 1)
        return bret;

    // TSRuntime::GetRemoteModulePath(process_name, pid, process_path);
    cpu = (DWORD)get_cpu_usage(pid);
    meminfo = (DWORD)GetMemoryInfo(pid);

    swprintf(retstring, L"%s|%s|%d|%d", process_name, process_path, cpu, meminfo);

    return bret;
}
bool WinApi::GetProcesspath(DWORD ProcessID, wchar_t *process_path)
{
    HANDLE hProcess = NULL;

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
                           ProcessID);

    HMODULE hMods = NULL;
    DWORD cbNeededModule = 0;
    EnumProcessModules(hProcess, &hMods, sizeof(hMods), &cbNeededModule);
    GetModuleFileNameExW(hProcess, hMods, process_path, MAX_PATH);

    return true;
}
bool WinApi::GetWindow(LONG hwnd, LONG flag, LONG &rethwnd)
{
    bool bret = false;
    rethwnd = 0;
    HWND wnd = (HWND)hwnd;
    if (IsWindow(wnd) == false)
        return bret;
    DWORD type = -1;
    if (flag == 0) // 0:获取父窗口
        rethwnd = (LONG)::GetParent(wnd);
    else if (flag == 1) // 获取第一个儿子窗口
        type = GW_CHILD;
    else if (flag == 2) // 获取First 窗口
        type = GW_HWNDFIRST;
    else if (flag == 3) // 获取Last窗口
        type = GW_HWNDLAST;
    else if (flag == 4) // 获取下一个窗口
        type = GW_HWNDNEXT;
    else if (flag == 5) // 获取上一个窗口
        type = GW_HWNDPREV;
    else if (flag == 6) // 获取拥有者窗口
        type = GW_OWNER;
    else if (flag == 7) // 获取顶层窗口
    {
        // rethwnd = (LONG)::GetForegroundWindow();
        HWND next = NULL, current = (HWND)hwnd;
        while (next = ::GetParent(current))
            current = next;
        rethwnd = (long)current;
        return ::IsWindow(current);
    }

    if (type != -1)
        rethwnd = (LONG)::GetWindow(wnd, (UINT)type);

    if (rethwnd != 0)
        bret = true;

    return bret;
}

bool WinApi::GetWindowState(LONG hwnd, LONG flag)
{
    bool bret = false;
    HWND wnd = (HWND)hwnd;
    if (flag == 0) // 0://判断窗口是否存在
        bret = ::IsWindow(wnd);
    else if (flag == 1) // 判断窗口是否处于激活
    {
        if (::GetActiveWindow() == wnd)
            bret = true;
    }
    else if (flag == 2) // 2 : 判断窗口是否可见
        bret = ::IsWindowVisible(wnd);
    else if (flag == 3) // 3 : 判断窗口是否最小化
        bret = ::IsIconic(wnd);
    else if (flag == 4) // 4 : 判断窗口是否最大化
        bret = ::IsZoomed(wnd);
    else if (flag == 5) // 5 : 判断窗口是否置顶
    {
        if (::GetForegroundWindow() == wnd)
            bret = true;
    }
    else if (flag == 6) // 6 : 判断窗口是否无响应
        bret = ::IsHungAppWindow(wnd);
    else if (flag == 7) // 判断窗口是否可用(灰色为不可用)
        bret = ::IsWindowEnabled(wnd);

    return bret;
}

bool WinApi::SendPaste(LONG hwnd)
{
    bool bret = true;
    HANDLE hClip;
    char *chBuffer = NULL;
    if (OpenClipboard(NULL))
    {
        // 从剪贴板中取出一个内存的句柄
        hClip = GetClipboardData(CF_TEXT);
        // 定义字符型指针变量用来保存内存块中的数据
        // 对内存块进行加锁，将内存句柄值转化为一个指针,并将内存块的引用计数器加一，内存中的数据也返回到指针型变量中
        chBuffer = (char *)GlobalLock(hClip);
        // 将数据保存到字符型变量中
        // 将内存块的引用计数器减一
        GlobalUnlock(hClip);
        // 关闭剪贴板，释放剪贴板资源的占用权
        CloseClipboard();
    }
    // anscii 转 unicode
    DWORD num = MultiByteToWideChar(CP_ACP, 0, chBuffer, -1, NULL, 0);
    wchar_t *wword = new wchar_t[num + 1];         // 动态的申请空间存字
    memset(wword, 0, (num + 1) * sizeof(wchar_t)); // 初始化动作
    MultiByteToWideChar(CP_ACP, 0, chBuffer, -1, wword, num);

    int len = wcslen(wword);
    // MessageBoxA(NULL,tts,tts,NULL);
    for (int i = 0; i < len; i++)
    {
        ::SendMessage((HWND)hwnd, WM_CHAR, (WPARAM)wword[i], (LPARAM)1);
        Sleep(10);
    }
    delete[] wword;

    return bret;
}

bool WinApi::SetWindowSize(LONG hwnd, LONG width, LONG hight, int type)
{
    bool bret = false;
    if (type == 0) // SetClientSize
    {
        RECT rectProgram, rectClient;
        HWND hWnd = (HWND)hwnd;
        ::GetWindowRect(hWnd, &rectProgram); // 获得程序窗口位于屏幕坐标
        ::GetClientRect(hWnd, &rectClient);  // 获得客户区坐标
        // 非客户区宽,高
        int nWidth = rectProgram.right - rectProgram.left -
                     (rectClient.right - rectClient.left);
        int nHeiht = rectProgram.bottom - rectProgram.top -
                     (rectClient.bottom - rectClient.top);
        nWidth += width;
        nHeiht += hight;
        rectProgram.right = nWidth;
        rectProgram.bottom = nHeiht;
        int showToScreenx =
            GetSystemMetrics(SM_CXSCREEN) / 2 - nWidth / 2; // 居中处理
        int showToScreeny = GetSystemMetrics(SM_CYSCREEN) / 2 - nHeiht / 2;
        bret = ::MoveWindow(hWnd, showToScreenx, showToScreeny, rectProgram.right,
                            rectProgram.bottom, false);
    }
    else // SetWindowSize
    {
        RECT rectClient;
        HWND hWnd = (HWND)hwnd;
        ::GetWindowRect(hWnd, &rectClient); // 获得程序窗口位于屏幕坐标
        bret = ::MoveWindow(hWnd, rectClient.left, rectClient.top, width, hight,
                            false);
    }
    return bret;
}

bool WinApi::SetWindowState(LONG hwnd, LONG flag, LONG rethwnd)
{
    bool bret = false;
    HWND hWnd = (HWND)hwnd;
    if (IsWindow(hWnd) == false)
        return bret;
    int type = -1;
    type = flag;
    if (flag == 0) // 关闭指定窗口
        ::SendMessage(hWnd, WM_CLOSE, 0, 0);
    else if (flag == 1) // 激活指定窗口
    {
        ::ShowWindow(hWnd, SW_SHOW);
        ::SetForegroundWindow(hWnd);
    }
    else if (flag == 2) // 最小化指定窗口,但不激活
        ::ShowWindow(hWnd, SW_SHOWMINNOACTIVE);
    else if (flag == 3) // 最小化指定窗口,并释放内存,但同时也会激活窗口
        ::ShowWindow(hWnd, SW_SHOWMINIMIZED);
    else if (flag == 4) // 最大化指定窗口,同时激活窗口.
        ::ShowWindow(hWnd, SW_SHOWMAXIMIZED);
    else if (flag == 5) // 恢复指定窗口 ,但不激活
        ::ShowWindow(hWnd, SW_SHOWNOACTIVATE);
    else if (flag == 6) // 隐藏指定窗口
        ::ShowWindow(hWnd, SW_HIDE);
    else if (flag == 7) // 显示指定窗口
    {
        ::ShowWindow(hWnd, SW_SHOW);
        ::SetForegroundWindow(hWnd);
    }
    else if (flag == 8) // 置顶指定窗口
        ::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0,
                       SWP_NOMOVE | SWP_NOSIZE); // 窗口置顶
    else if (flag == 9)                          // 9 : 取消置顶指定窗口
        ::SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    else if (flag == 10) // 禁止指定窗口
        ::EnableWindow(hWnd, false);
    else if (flag == 11) // 取消禁止指定窗口
        ::EnableWindow(hWnd, true);
    else if (flag == 12) // 12 : 恢复并激活指定窗口
        ::ShowWindow(hWnd, SW_RESTORE);
    else if (flag == 13) // 13 : 强制结束窗口所在进程.
    {
        DWORD pid = 0;
        ::GetWindowThreadProcessId(hWnd, &pid);
        // TSRuntime::EnablePrivilege(L"SeDebugPrivilege", true);
        HANDLE hprocess = NULL;

        hprocess = ::OpenProcess(PROCESS_ALL_ACCESS, false, pid);

        ::TerminateProcess(hprocess, 0);
    }
    else if (flag == 14) // 14 : 闪烁指定的窗口
    {
        FLASHWINFO fInfo;
        fInfo.cbSize = sizeof(FLASHWINFO);
        fInfo.dwFlags =
            FLASHW_ALL |
            FLASHW_TIMERNOFG; // 这里是闪动窗标题和任务栏按钮,直到用户激活窗体
        fInfo.dwTimeout = 0;
        fInfo.hwnd = hWnd;
        fInfo.uCount = 0xffffff;
        FlashWindowEx(&fInfo);
    }
    else if (flag == 15) // 使指定的窗口获取输入焦点
    {
        ::ShowWindow(hWnd, SW_SHOW);
        ::SetFocus(hWnd);
    }

    if (type >= 0 && type < 16)
        bret = true;

    return bret;
}

bool WinApi::SetWindowTransparent(LONG hwnd, LONG trans)
{
    bool bret = false;

    COLORREF crKey = NULL;
    DWORD dwFlags = 0;
    BYTE bAlpha = 0;
    if (trans < 0)
        trans = 0;
    if (trans > 255)
        trans = 255;
    //...
    /*typedef bool(__stdcall  *  mySetLayeredWindowAttributes)(
            HWND hwnd,
            COLORREF pcrKey,
            BYTE pbAlpha,
            DWORD pdwFlags);
    mySetLayeredWindowAttributes obj_SetLayeredWindowAttributes = NULL;
    HINSTANCE hlibrary;
    hlibrary = LoadLibrary(_T("user32.dll"));
    obj_SetLayeredWindowAttributes =
    (mySetLayeredWindowAttributes)GetProcAddress(hlibrary,
    "SetLayeredWindowAttributes");*/

    SetWindowLong((HWND)hwnd, GWL_EXSTYLE, 0x80001);
    bret = SetLayeredWindowAttributes((HWND)hwnd, crKey, trans, 2);

    return bret;
}

bool WinApi::SetClipboard(const wchar_t *values)
{
    bool bret = false;
    int n = ::WideCharToMultiByte(CP_ACP, 0, values, -1, NULL, 0, NULL, NULL);
    char *chcontent = new char[n + 1];
    memset(chcontent, 0, sizeof(char) * n + 1);
    WideCharToMultiByte(CP_ACP, 0, values, -1, chcontent, n, NULL, NULL);

    if (OpenClipboard(NULL))
    {
        // 将剪贴板内容清空
        EmptyClipboard();
        // 字节长度
        int leng = strlen(chcontent) + 1;
        // 在堆上分配可移动的内存块，程序返回一个内存句柄
        HANDLE hClip = GlobalAlloc(GHND | GMEM_SHARE, leng);
        // 定义指向字符型的指针变量
        char *buff;
        // 对分配的内存块进行加锁，将内存块句柄转化成一个指针,并将相应的引用计数器加一
        buff = (char *)GlobalLock(hClip);
        // 将用户输入的数据拷贝到指针变量中，实际上就是拷贝到分配的内存块中
        memcpy(buff, chcontent, leng);
        buff[leng - 1] = 0;
        // 数据写入完毕，进行解锁操作，并将引用计数器数字减一
        GlobalUnlock(hClip);
        // 将存放有数据的内存块放入剪贴板的资源管理中
        HANDLE help = SetClipboardData(CF_TEXT, hClip);
        // 关闭剪贴板，释放剪贴板资源的占用权
        CloseClipboard();
        // MessageBox(0,L"已将数据存入剪贴板",L"剪切扳",0);
        if (help != NULL)
        {
            bret = true;
        }
        else
        {
            bret = false;
        }
    }
    delete[] chcontent;
    return bret;
}

bool WinApi::GetClipboard(std::wstring &retstr)
{
    bool bret = false;
    HANDLE hClip;
    char *chBuffer = NULL;
    if (!OpenClipboard(NULL))
        return bret;

    // 从剪贴板中取出一个内存的句柄
    hClip = GetClipboardData(CF_TEXT);
    // 定义字符型指针变量用来保存内存块中的数据

    // 对内存块进行加锁，将内存句柄值转化为一个指针,并将内存块的引用计数器加一，内存中的数据也返回到指针型变量中
    chBuffer = (char *)GlobalLock(hClip);

    // 将数据保存到字符型变量中
    // 将内存块的引用计数器减一
    GlobalUnlock(hClip);
    // 关闭剪贴板，释放剪贴板资源的占用权
    CloseClipboard();

    DWORD num = MultiByteToWideChar(CP_ACP, 0, chBuffer, -1, NULL, 0);
    wchar_t *wword = new wchar_t[num + 1];         // 动态的申请空间存字
    memset(wword, 0, (num + 1) * sizeof(wchar_t)); // 初始化动作
    MultiByteToWideChar(CP_ACP, 0, chBuffer, -1, wword, num);

    retstr.append(wword);
    delete[] wword;

    return bret;
}

long WinApi::SendString(HWND hwnd, const wstring &s)
{
    if (::IsWindow(hwnd))
    {
        auto p = s.data();
        for (int i = 0; i < s.length(); ++i)
        {
            ::PostMessageW(hwnd, WM_CHAR, p[i], 0);
            ::Sleep(5);
        }
        return 1;
    }
    return 0;
}

long WinApi::SendStringIme(HWND hwnd, const wstring &s)
{
    if (::IsWindow(hwnd))
    {
        auto p = s.data();
        for (int i = 0; i < s.length(); ++i)
        {
            ::PostMessage(hwnd, WM_IME_CHAR, p[i], 0);
            ::Sleep(5);
        }
        return 1;
    }
    return 0;
}

long WinApi::RunApp(const wstring &cmd, long mode)
{
    std::unique_ptr<wchar_t> cmdptr(new wchar_t[cmd.length() + 1]);
    memcpy(cmdptr.get(), cmd.data(), cmd.length() * sizeof(wchar_t));
    cmdptr.get()[cmd.length()] = 0; // C字符串需要末尾有0
    /*SECURITY_ATTRIBUTES SA;
    SA.bInheritHandle = NULL;
    SA.*/
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    ZeroMemory(&pi, sizeof(pi));
    int bret;
    wstring curr_dir;
    if (mode == 1)
    {
        // find
        size_t pos;
        pos = cmd.find(L".exe");
        if (pos != wstring::npos && pos != 0)
        {
            for (int i = pos - 1; i >= 1; --i)
            {
                if (cmd[i] == L'\\' || cmd[i] == L'/')
                {
                    pos = i;
                    break;
                }
            }
            if (pos > 0)
            {
                curr_dir = cmd.substr(0, pos);
            }
        }
        // setlog(curr_dir.c_str());
    }
    bret = ::CreateProcessW(
        nullptr,      //// 应用程序名称
        cmdptr.get(), // 命令行字符串
        NULL,         // 进程的安全属性
        NULL,         // 线程的安全属性
        false,        // 是否继承父进程的属性
        0,            // 创建标志
        nullptr,      // 指向新的环境块的指针
        mode == 1 && !curr_dir.empty() ? curr_dir.c_str()
                                       : nullptr, // 指向当前目录名的指针
        &si,                                      // 传递给新进程的信息
        &pi                                       // 新进程返回的信息
    );
    if (bret)
    {
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }

    return bret;
}

HWND WinApi::GetTopWindowSp(HWND hwnd)
{
    HWND i = hwnd, temp;

    while (GetWindowLongA(i, GWL_STYLE) > 0)
    {
        temp = GetParent(i);
        if (!temp)
            break;
    }
    return i;
}

std::mutex g_lockToTop;
HWND g_lastTopWin = NULL;
void WinApi::LockBringWinToTop(HWND hwnd)
{
    g_lockToTop.lock();
    if (g_lastTopWin != hwnd)
    {
        ::SetForegroundWindow(hwnd);
        g_lastTopWin = hwnd;
        Sleep(200 + rand() % 100);
    }
}

void WinApi::UnLockBringWinToTop()
{
    g_lockToTop.unlock();
}
